import 'dart:convert';
import 'dart:io';
import 'package:cookie_jar/cookie_jar.dart';
import 'package:chop/Model/DistanceEntity.dart';
import 'package:chop/Model/LoginEntity.dart';
import 'package:chop/Model/POLI_entity.dart';
import 'package:chop/Model/address_entity.dart';
import 'package:chop/Model/ajax_request_entity.dart';
import 'package:chop/Model/order_entity.dart';
import 'package:chop/Model/order_img_entity.dart';
import 'package:chop/Model/priceEntity.dart';
import 'package:dio/dio.dart';
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
import 'package:geolocator/geolocator.dart';
import 'Methods.dart';
import 'configs.dart';

Dio dio = Dio(); // 使用默认配置
var cookieJar = CookieJar();

class DioUtils {
  static initDioOptions() {
    // 配置dio实例
    dio.options.baseUrl = Configs.URL;
    dio.options.connectTimeout = 40000; //5s
    dio.options.receiveTimeout = 300000;
    dio.interceptors.add(CookieManager(cookieJar));
  }

  static Future request(
      Methods methods, String method, Map<String, Object> mapParams,
      {bool isGoogle = false}) async {
    Response res;
    try {
      print(
          "============================${methods.toString()}请求开始============================");
      String strParams = "";
      if (methods == Methods.GET) {
        mapParams.forEach((k, v) {
          strParams += "$k=$v&";
        });
        if (strParams
            .substring(strParams.length - 1, strParams.length)
            .contains("&")) {
          strParams = strParams.substring(0, strParams.length - 1);
        }

        if (isGoogle) {
          print("请求google地址：${Configs.GoogleURL}$method?$strParams");
          res = await dio.get(
            Configs.GoogleURL + method + "?" + strParams,
          );
        } else {
          print("请求地址：${Configs.URL}$method?$strParams");
          res = await dio.get(
            Configs.URL + method + "?" + strParams,
          );
        }
      } else if (methods == Methods.POST) {
        if (isGoogle) {
          print(
              "请求google地址：${Configs.GoogleURL + method} \r\n 表单数据：${mapParams.toString()}");
          FormData formData = FormData.fromMap(mapParams);
          res = await dio.post(Configs.GoogleURL + method, data: formData);
        } else {
          print(
              "请求地址：${Configs.URL + method} \r\n 表单数据：${mapParams.toString()}");
          FormData formData = FormData.fromMap(mapParams);
          res = await dio.post(Configs.URL + method, data: formData);
        }
      }
      print("返回数据：${res}");
      print(
          "============================${methods.toString()}请求结束============================");
      return res;
    } catch (e) {
      print(e);
      return new Response(data: {"code": 500, "msg": "服务器连接失败"});
    }
  }

  static Future requestByPaging(
      Methods methods, String method, Map<String, Object> mapParams) async {
    try {
      print(
          "============================${methods.toString()}请求开始============================");
      //pageSize=10&pageNum=$pageNum&orderByColumn=pAddDatetime
      mapParams["pageSize"] = 10;
      Response res;
      if (methods == Methods.GET) {
        String strParams = "";
        mapParams.forEach((k, v) {
          strParams += "$k=$v&";
        });
        if (strParams
            .substring(strParams.length - 1, strParams.length)
            .contains("&")) {
          strParams = strParams.substring(0, strParams.length - 1);
        }
        print("请求地址：${Configs.URL}$method?$strParams");
        res = await dio.get(
          Configs.URL + method + "?" + strParams,
        );
      } else if (methods == Methods.POST) {
        FormData formData = FormData.fromMap(mapParams);
        print(
            "请求地址：${Configs.URL + method}  \r\n  表单数据：${mapParams.toString()}");
        res = await dio.post(
          Configs.URL + method,
          data: formData,
        );
      }
      print("返回数据：${res.data}");
      print(
          "============================${methods.toString()}请求结束============================");
      return res;
    } catch (e) {
      print(e);
      if (e.type == DioErrorType.CONNECT_TIMEOUT) {
        return json.encode({"code": 500, "msg": "服务器连接失败"});
      }
    }
  }




  /**
   * 获取最近路线距离
   */
  static Future<Map> getTime(Position begin, Position end) async {
    Response response = await request(
        Methods.GET,
        "distancematrix/json",
        {
          "origins": "${begin.latitude},${begin.longitude}",
          "key": Configs.API_KEY,
          "destinations": "${end.latitude},${end.longitude}"
        },
        isGoogle: true);
    print(response);
    Map m = json.decode(response.toString());
    return m;
  }

  /**
   * 计算价格
   */
  static Future<priceEntity> getPrice(String range) async {
    Response response =
        await request(Methods.POST, "app/getPrice", {"range": range});
    print(response);
    Map m = json.decode(response.toString());
    return priceEntity.fromJson(m);
  }

  // 路程距离
  static Future aDemo(Position begin, Position end) async {
    Response response = await request(
        Methods.GET,
        "directions/json",
        {
          "origin": "${begin.latitude},${begin.longitude}",
          "key": Configs.API_KEY,
          "destination": "${end.latitude},${end.longitude}"
        },
        isGoogle: true);
    print(response);
    return response;
  }

  /**
   * 新增常用地址
   */
  static Future<AjaxRequest> addAddress(AdrEntityData adrEntityData) async {
    Response response =
        await request(Methods.POST, "app/addAddress", adrEntityData.toJson());
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  /**
   * 查询地址集合
   */
  static Future<AdrEntity> selectByUID(String UID, String sOrT) async {
    Response response = await request(
        Methods.POST, "app/selectByUID", {"UID": "$UID", "sOrT": sOrT});
    print(response);
    Map m = json.decode(response.toString());
    return AdrEntity.fromJson(m);
  }

  /**
   * 查询订单列表
   */
  static Future<Map> orderList(orderData data) async {
    Response response =
        await request(Methods.POST, "app/orderList", data.toJson());
    print(response);
    Map m = json.decode(response.toString());
    return m;
  }

  /**
   * 查询未接单订单列表
   */
  static Future<Map> unOrders(String status,String lat, String lng) async {
    Response response =
    await request(Methods.POST, "app/unOrders", {"status":status,"lat":lat,"lng":lng});
    print(response);
    Map m = json.decode(response.toString());
    return m;
  }
//  /**
//   * 查询未接单订单列表
//   */
//  static Future<Map> unOrders(String status,String lat, String lng) async {
//    Response response =
//    await request(Methods.POST, "app/unOrders", {"status":status,"lat":lat,"lng":lng});
//    print(response);
//    Map m = json.decode(response.toString());
//    return m;
//  }

  /**
   * 查询订单信息
   */
  static Future<Map> orderInfo(String UID) async {
    Response response =
        await request(Methods.POST, "app/orderInfo", {"uuid": "$UID"});
    Map m = json.decode(response.toString());
    return m;
  }

  /**
   * 删除订单
   */
  static Future<Map> delOrder(String UID) async {
    Response response =
        await request(Methods.POST, "app/delOrder", {"uuid": "$UID"});
    print(response);
    Map m = json.decode(response.toString());
    return m;
  }

  /**
   * 下单
   */
  static Future<OrderEntity> orderAdd(orderData orderData) async {
    Response response =
        await request(Methods.POST, "/app/addOrder", orderData.toJson());
    print(response);
    Map m = json.decode(response.toString());
    return OrderEntity.fromJson(m);
  }

  /**
   * 请求骑手数据
   */
  static Future<AjaxRequest> riderInfo(String userId) async {
    Response response =
        await request(Methods.POST, "/app/riderInfo", {"userId": "$userId"});
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  /**
   * 开始接单
   */
  static Future<AjaxRequest> riderOpen(String userId) async {
    Response response =
        await request(Methods.POST, "/app/riderOpen", {"userId": "$userId"});
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  /**
   * 更新订单位置
   */
  static Future<AjaxRequest> updateNewAddress(String userId,
      {String lat, String lng}) async {
    Response response = await request(Methods.POST, "/app/updateNewAddress",
        {"uid": "$userId", "lat": "$lat", "lng": "$lng"});
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  /**
   * 骑手更新订单
   */
  static Future<AjaxRequest> orderUpdateRider(
      orderData order, String orderinfo) async {
    Response response = await request(Methods.POST, "/app/orderUpdateRider", {
      "uuid": order.uuid,
      "status": order.status,
      "riderId": order.riderId,
      "riderName": order.riderName,
      "orderInfo": orderinfo
    });
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  /**
   * 获取进行中订单详细
   */
  static Future<AjaxRequest> orderInfoList(String oid) async {
    Response response = await request(Methods.POST, "/app/orderInfoList", {
      "oid": oid,
    });
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  static Future<POLIEntity> sendPOLI(orderData data) async {
    Response response =
        await DioUtils.request(Methods.POST, '/pay/sendPOLI', data.toJson());
    Map m = json.decode(response.toString());
    return POLIEntity.fromJson(m);
  }

  /**
   * 验证码登录
   */
  static Future<LoginEntity> login(
    bool isRider, {
    username,
    password,
  }) async {
    Map<String, Object> params = {
      "phone": username,
      "password": password,
      "isRider": isRider
    };
    Response result = await request(Methods.POST, "/app/logUser", params);
    Map map = json.decode(result.toString());
    LoginEntity loginResultEntity = LoginEntity.fromJson(map);
    print(">>>>>>>>>>>>>>>>登录完成<<<<<<<<<<<<<\n");
    return loginResultEntity;
  }

  /**
   * 发送验证码
   */
  static Future<Map> sendSMS({String phone,String type}) async {
    Map<String, Object> params = {
      "phone": phone,
      "smsType": type
    };
    Response result = await request(Methods.POST, "/app/sendSMS", params);
    Map map = json.decode(result.toString());
    LoginEntity loginResultEntity = LoginEntity.fromJson(map);
    print(">>>>>>>>>>>>>>>>发送完成<<<<<<<<<<<<<\n");
    return map;
  }

  /**
   * 登录
   */
  static Future<LoginEntity> signUser(
    bool isRider, {
    username,
    password,
  }) async {
    Map<String, Object> params = {
      "phone": username,
      "password": password,
      "isRider": isRider
    };
    Response result = await request(Methods.POST, "/app/signUser", params);
    Map map = json.decode(result.toString());
    LoginEntity loginResultEntity = LoginEntity.fromJson(map);
    print(">>>>>>>>>>>>>>>>登录完成<<<<<<<<<<<<<\n");
    return loginResultEntity;
  }

  /**
   * 注册
   */
  static Future<LoginEntity> signUp(
      bool isRider, {
        username,
        password,
      }) async {
    Map<String, Object> params = {
      "phone": username,
      "password": password,
      "isRider": isRider
    };
    Response result = await request(Methods.POST, "/app/signUp", params);
    Map map = json.decode(result.toString());
    LoginEntity loginResultEntity = LoginEntity.fromJson(map);
    print(">>>>>>>>>>>>>>>>登录完成<<<<<<<<<<<<<\n");
    return loginResultEntity;
  }


  static Future<AjaxRequest> imgAdd(OrderImg img) async {
    Response response = await request(Methods.POST, "/app/addImg",
        img.toJson());
    print(response);
    Map m = json.decode(response.toString());
    return AjaxRequest.fromJson(m);
  }

  // 上传图片
  static Future uploadImg(imgfile) async{
    String path = imgfile.path;
    var name = path.substring(path.lastIndexOf("/") + 1, path.length);
    FormData formData = FormData.fromMap({
      "file": await MultipartFile.fromFile(path, filename: name)
    });
    Response response;
    print(formData.toString());
    response =await dio.post(Configs.URL + "/common/upload",data: formData);
    if(response.statusCode == 200){
      return response.data;
    }else{
      throw Exception("后端接口异常");
    }
  }
}

